﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GN.Pay.TradeChannel;
using GN.Pay.Core.Services;
using Abp.Domain.Uow;
using Abp.Dependency;
using GN.Pay.Core.Repositories;
using GN.Pay.Core.Exceptions;
using GN.Pay.Core.Entities;
using GN.Pay.TradeChannel.Transfers;

namespace GN.Pay.Application.GatewayApp.Impl
{
    /// <summary>
    /// 交易通知应用服务
    /// </summary>
    public class TradeNotifyAppService : GatewayAppService, ITradeNotifyAppService
    {
        private readonly IIocManager iocManager;

        public TradeNotifyAppService(IIocManager iocManager)
        {
            this.iocManager = iocManager;
        }

        class ChannelMessage
        {
            public string AppId { get; set; }

            public string ChannelId { get; set; }
        }

        /// <summary>
        /// 根据交易号获取通道
        /// </summary>
        /// <param name="tradeNo">交易号</param>
        /// <returns></returns>
        ITradeChannel ITradeNotifyAppService.GetPayTradeChannel(string tradeNo)
        {
            var service = iocManager.Resolve<ITradeCacheService>();
            var notify = service.GetPayReturnNotify(tradeNo);
            if (notify != null)
            {
                var data = notify.GetPayNotifyData();
                if (data != null)
                {
                    return service.GetTradeChannel(notify.AppId, data.ChannelId);
                }
            }
            PayExceptionUtils.CheckNotNullOrNotWhiteSpace(tradeNo, nameof(tradeNo));
            var rep1 = iocManager.Resolve<ITradePayApplyChannelRepository>();
            var rep2 = iocManager.Resolve<ITradePayApplyRepository>();
            var msg = (from p in rep1.GetAll()
                       join m in rep2.GetAll() on p.ApplyId equals m.Id
                       where p.Id == tradeNo
                       select new ChannelMessage()
                       {
                           AppId = m.AppId,
                           ChannelId = p.ChannelId
                       }).FirstOrDefault();
            if (msg == null)
            {
                var rep3 = iocManager.Resolve<ITradeAccountBookChannelRepository>();
                var rep4 = iocManager.Resolve<ITradeAccountBookRepository>();

                msg = (from p in rep3.GetAll()
                       join m in rep4.GetAll() on p.BookId equals m.Id
                       where p.Id == tradeNo
                       select new ChannelMessage()
                       {
                           AppId = m.AppId,
                           ChannelId = p.ChannelId
                       }).FirstOrDefault();
            }
            if (msg == null)
            {
                return null;
            }
            return service.GetTradeChannel(msg.AppId, msg.ChannelId);
        }

        /// <summary>
        /// 根据退款批号获取通道
        /// </summary>
        /// <param name="refundNo">退款交易号</param>
        /// <returns></returns>
        ITradeChannel ITradeNotifyAppService.GetRefundTradeChannel(string refundNo)
        {
            PayExceptionUtils.CheckNotNullOrNotWhiteSpace(refundNo, nameof(refundNo));
            var rep1 = iocManager.Resolve<ITradeRefundApplyRepository>();
            var msg = (from q in rep1.GetAll()
                       where q.RefundTradeNo == refundNo
                       select new ChannelMessage()
                       {
                           AppId = q.AppId,
                           ChannelId = q.ChannelId
                       }).FirstOrDefault();
            if (msg == null)
            {
                var rep2 = iocManager.Resolve<ITradeRefundBookRepository>();
                msg = (from q in rep2.GetAll()
                       where q.RefundTradeNo == refundNo
                       select new ChannelMessage()
                       {
                           AppId = q.AppId,
                           ChannelId = q.ChannelId
                       }).FirstOrDefault();
            }
            if (msg == null)
            {
                return null;
            }
            var service = iocManager.Resolve<ITradeCacheService>();
            return service.GetTradeChannel(msg.AppId, msg.ChannelId);
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="tradeNo">交易号</param>
        /// <returns></returns>
        public TradeNotify GetCacheTradeNotify(string tradeNo)
        {
            var service = iocManager.Resolve<ITradeCacheService>();
            return service.GetPayReturnNotify(tradeNo);
        }

        /// <summary>
        /// 订单付款通知
        /// </summary>
        /// <param name="order"></param>
        public void OrderPayNotify(ITradeOrderQueryResult order)
        {
            var service = iocManager.Resolve<ITradeNotifyService>();
            service.PayNotify(order);
        }

        /// <summary>
        /// 订单退款通知
        /// </summary>
        /// <param name="apply"></param>
        public void OrderRefundNotify(ITradeRefundApplyResult apply)
        {
            var service = iocManager.Resolve<ITradeNotifyService>();
            service.RefundNotify(apply);
        }

        /// <summary>
        /// 转账通知
        /// </summary>
        /// <param name="result"></param>
        public void TransfersNotify(ITransfersApplyResult result)
        {
            var service = iocManager.Resolve<ITradeNotifyService>();
            service.TransfersNotify(result);
        }
    }
}
